#ifndef BAS_BAS_LIST_H
#define BAS_BAS_LIST_H

#include <stdbool.h>
#include <stdlib.h>
#include "bas/bas_const.h"
#include "bas/bas_iterator.h"
#include "bas/bas_list_private.h"

/**
 * @brief     创建一个List列表容器
 * @param[in] tTypeInfo 类型信息, 使用_T()宏来得到类型信息，具体可以查看_T()宏的文档
 * @returns   指向列表的指针, 创建失败返回NULL
 * @note      samples:
 *                1.不指定任何类型函数
 *                  T_List *ptList = basListCreate(_T(T_YourStruct));
 *                2.指定销毁函数, 和拷贝函数(用于结构体中存在指针,需要自行进行释放, 以免内存泄露)                   
 *                  如果你需要一个销毁函数, 往往你也需要一个拷贝函数, 否则将会带来内存泄露
 *                  T_List *ptList = basListCreate(_T(T_YourStruct, pfnDestory, pfnCopy));
 *                3.指定小于比较函数指针,拷贝函数指针,初始化函数指针(用于算法,以及容器复制等操作)
 *                  T_List *ptList = basListCreate(_T(T_YourStruct, pfnDestory, pfnCopy, pfnLess, pfnInit));
 *                4.元素为内置字符串类型
 *                  T_List *ptList = basListCreate(_T(BUILDIN_STRING));
 */
T_List *basListCreate(const T_TypeInfo tTypeInfo);

/**
 * @brief     销毁List列表容器
 * @param[in] ptList 指向List的指针
 */
void basListDestroy(T_List *ptList);

/**
 * @brief     清空List列表容器, 删除其中所有的元素
 * @param[in] ptList 指向List的指针
 */
void basListClear(T_List *ptList);

/**
 * @brief     返回List中元素的个数
 * @param[in] ptList 指向List的指针
 * @returns   List中元素的个数
 */
size_t basListSize(const T_List *ptList);

/**
 * @brief     调整当前List中元素的个数为nSize个
 * @param[in] ptList          指向List的指针
 * @param[in] nSize           调整后List中元素的个数
 * @param[in] pvInitParameter 可变参数为初始化函数的参数
 * @returns   0 - 成功　-1 - 失败
 * @note      1.如果nSize小于List中当前的元素个数, 则舍弃除了前nSize以后的所有元素, 并且调用销毁函数(如果有的话),
 *              此时指向被释放元素的迭代器失效
 *            2.如果nSize大于List中当前的元素个数, 多余的元素使用初始化函数进行初始化
 *              (如果未指定初始化函数, 默认填0), 可变参数为初始化函数的参数
 *            3.如果nSize小于0, 什么也不做
 *            samples:
 *                1.未指定初始化函数
 *                  basListResize(ptList, 10);
 *                2.指定了初始化函数
 *                  basListResize(ptList, 10, pvInitParameter);
 */
#define basListResize(_ptList, _nSize, ...) _basListResize(_ptList, _nSize, ##__VA_ARGS__, BAS_PARM_END)

/**
 * @brief     测试List是否为空
 * @param[in] ptList 指向List的指针
 * @returns   true - List为空  false - List不为空
 */
bool basListEmpty(const T_List *ptList);

/**
 * @brief     在List末尾添加一个新元素
 * @param[in] ptList  指向List的指针
 * @param[in] element 对于内置类型, 该参数为内置类型本身, 对于用户定义的结构体类型,该参数为结构体指针
 * @returns   0 - 成功 -1 - 失败
 * @see       basVectorPushBack
 */
int basListPushBack(T_List *ptList, ...);

/**
 * @brief     在List末尾删除一个元素, 并且调用销毁函数(如果有的话)
 * @param[in] ptList 指向List的指针
 * @note      若List为空, 什么也不做
 * @warning   该操作使指向该元素的迭代器失效
 */
void basListPopBack(T_List *ptList);

/**
 * @brief     在List开头添加一个新元素
 * @param[in] ptList  指向List的指针
 * @param[in] element  对于内置类型, 该参数为内置类型本身, 对于用户定义的结构体类型,该参数为结构体指针
 * @returns   0 - 成功 -1 - 失败
 * @see       basVectorPushBack
 */
int basListPushFront(T_List *ptList, ...);

/**
 * @brief     在List开头删除一个元素, 并且调用销毁函数(如果有的话)
 * @param[in] ptList 指向List的指针
 * @note      若List为空, 什么也不做
 * @warning   该操作使指向该元素的迭代器失效
 */
void basListPopFront(T_List *ptList);

/**
 * @brief     返回指向List第一个元素的迭代器, 类型为双向迭代器
 * @param[in] ptVector 指向List的指针
 * @returns   指向List第一个元素的迭代器 
 */
T_Iterator basListBegin(const T_List *ptList);

/**
 * @brief     返回指向List末尾(最后一个元素之后)的迭代器(哨兵迭代器), 类型为双向迭代器
 * @param[in] ptList 指向List的指针
 * @returns   指向List末尾的迭代器
 * @note      返回的迭代器作为哨兵使用, 并不指向实际的元素
 */
T_Iterator basListEnd(const T_List *ptList);

/**
 * @brief     返回指向List最后一个元素的迭代器, 类型为双向迭代器
 * @param[in] ptList 指向List的指针
 * @returns   指向List最后一个元素的迭代器 
 */
T_Iterator basListRBegin(const T_List *ptList);

/**
 * @brief     返回指向List开头(第一个元素之前)的迭代器(哨兵迭代器), 类型为双向迭代器
 * @param[in] ptList 指向List的指针
 * @returns   指向List开头的迭代器
 * @note      返回的迭代器作为哨兵使用, 并不指向实际的元素
 */
T_Iterator basListREnd(const T_List *ptList);

/**
 * @brief     在迭代器tIterator的位置前插入一个元素
 * @param[in] ptList    指向List的指针
 * @param[in] tIterator 迭代器
 * @param[in] element   对于内置类型, 该参数为内置类型本身, 对于用户定义的结构体类型,该参数为结构体指针
 * @returns   指向新插入元素的迭代器, 如果失败返回无效迭代器, 使用basIteratorIsValid来检查返回值
 * @see       basIteratorIsValid basVectorPushBack
 */
T_Iterator basListInsert(T_List *ptList, const T_Iterator tIterator, ...);

/**
 * @brief     清除迭代器tIterator所指向的元素 
 * @param[in] ptList    指向List的指针
 * @param[in] tIterator 迭代器
 * @returns   指向被删除元素下一个元素的迭代器, 如果被删除元素是最后一个元素, 返回容器末尾的哨兵迭代器
 * @note      如果指定了销毁函数, 则在清除元素前会调用销毁函数
 */
T_Iterator basListErase(T_List *ptList, const T_Iterator tIterator);

/**
 * @brief     对List中的的元素进行排序
 * @param[in] ptList  指向List的指针
 * @param[in] pfnLess 可变参数, 小于比较函数
 * @note      1.排序时使用的小于比较函数选择优先级为:
 *              (1)basListSort可变参数中指定的比较函数
 *              (2)basListCreate中指定的比较函数(如果为内置类型, 则使用内置的比较函数)
 *              (3)memcmp, 二进制比较
 *            2.排序是stable的
 *            samples:
 *                1.未指定小于比较函数 
 *                  basListSort(ptList);
 *                2.指定小于比较函数
 *                  basListSort(ptList, pfnLess);
 */
#define basListSort(_ptList, ...) _basListSort(_ptList, ##__VA_ARGS__, BAS_PARM_END)

#endif
